package com.itelite.controller;



import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.itelite.aop.WinControllerPointCut;
import com.itelite.common.info.ExcelStyleUtil;
import com.itelite.common.info.Result;
import com.itelite.common.util.ExtUtils;

import com.itelite.common.util.SecurityUtils;
import com.itelite.common.util.SpringUtils;
import com.itelite.domain.dto.*;
import com.itelite.domain.pojo.Group;
import com.itelite.handler.ValidateHandler;
import com.itelite.service.GroupService;
import com.itelite.service.RecordService;
import com.itelite.service.TeacherService;
import com.itelite.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.*;

/**
 * @author 沈洋 邮箱:1845973183@qq.com
 * @create 2021/8/2-22:43
 **/
@Api("管理员模块")
@Slf4j
@RestController
@RequestMapping("/admin/api")
public class AdminController {
    @Autowired
    private UserService userService;
    @Autowired
    private GroupService groupService;
    @Autowired
    private RecordService recordService;
    private final static String FILE_TYPE_OF_EXCEL="application/vnd";

    /**
     * 下载Excel
     *
     */
    @PreAuthorize("hasAnyRole('ADMIN','USER')")
    @ApiOperation("下载学生导入模板")
    @GetMapping(value = "/downloadUserModel")
    @WinControllerPointCut
    public void downloadUserModel(HttpServletResponse response) throws IOException {
        //获取导出参数
        ExportParams exportParams = new ExportParams("IT培优学生信息导入", "sheet1", ExcelType.HSSF);
        //设置导出样式
        exportParams.setStyle(ExcelStyleUtil.class);
        //设置行高
        exportParams.setHeight((short) 6);
        //输出Workbook流
        Workbook workbook = ExtUtils.exportExcel(exportParams, UploadUser.class, new ArrayList<>());
        int year = Calendar.getInstance().get(Calendar.YEAR);
        String[] years = new String[10];
        for (int i = 0; i <10 ; i++,year--) {
            years[i]=String.valueOf(year);
        }
        String[] groups = groupService.getImportableGroup();
        //设置下拉框（从0开始）
        ExtUtils.selectList(workbook, 3, 3,new String[]{"男","女"});
        ExtUtils.selectList(workbook, 4, 4,years);
        ExtUtils.selectList(workbook,5,5,groups);
        ExtUtils.downLoadExcel("IT培优学生信息导入.xls", response,workbook );
    }

    @PostMapping("/downloadTeacherTrainRecord")
    @ApiOperation("下载老师培训量化表")
    @PreAuthorize("hasRole('ADMIN')")
    @WinControllerPointCut
    public void downloadTeacherTrainRecord(@RequestBody RecordParam param, HttpServletResponse response) throws IOException, ExecutionException, InterruptedException {
        Group root = null;
        if(param.getGroupId()==null||(root=groupService.getGroupRoot(param.getGroupId()))==null){
            SpringUtils.makeResponse(response,Result.failure("组号缺少或错误"));
            return;
        }
        log.info("下载小组: "+param.getGroupId());
        //使用线程池
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        //获取导出参数
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日HH时");
        String title = sdf.format(param.getStartDate())+"——"+sdf.format(param.getEndDate());
        Queue<Group> queue = new LinkedList<>();
        queue.add(root);
        //构造sheet
        List<Map<String, Object>> sheetsList = new ArrayList<>();
        while (!queue.isEmpty()){
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                Group p = queue.poll();
                assert p != null;
                RecordParam t = new RecordParam();
                t.setStartDate(param.getStartDate());
                t.setEndDate(param.getEndDate());
                t.setGroupId(p.getGroupId());
                executorService.submit(() -> {
                    log.info(param.getGroupId()+"查询组");
                    //查询组
                    List<TeacherRecordExcel> list = recordService.getTeacherTrainingRecord(t);
                    //为空则进行下一个
                    if(!CollectionUtils.isEmpty(list)) {
                        // 创建参数对象（用来设定excel得sheet得内容等信息）
                        ExportParams exportParams = new ExportParams();
                        // 设置sheet得名称
                        exportParams.setSheetName(p.getGroupName());
                        //设置导出样式
                        exportParams.setStyle(ExcelStyleUtil.class);
                        //设置行高
                        exportParams.setHeight((short) 6);
                        exportParams.setTitle(title);
                        // 创建sheet1使用得map
                        Map<String, Object> exportMap = new HashMap<>();
                        // title的参数为ExportParams类型，目前仅仅在ExportParams中设置了sheetName
                        exportMap.put("title", exportParams);
                        // 模版导出对应得实体类型
                        exportMap.put("entity", TeacherRecordExcel.class);
                        // sheet中要填充得数据
                        exportMap.put("data", list);
                        sheetsList.add(exportMap);
                    }
                });
                queue.addAll(p.getChildren());
            }
        }
        //不在接收新的任务
        executorService.shutdown();
        // 等待所有线程执行完毕
        try {
            // 等待所有线程执行完毕
            boolean flag = executorService.awaitTermination(Long.MAX_VALUE,TimeUnit.NANOSECONDS);
            if(flag){
                log.info("线程池执行结束");
            }else log.info("线程池未执行结束");
        } catch (InterruptedException e) {
            log.error(e.getMessage());
        }
        //sheet中没有数据直接返回信息
        if (sheetsList.isEmpty()){
            SpringUtils.makeResponse(response,Result.failure("无数据"));
            return;
        }
        Workbook workbook = ExcelExportUtil.exportExcel(sheetsList, ExcelType.HSSF);
        //输出Workbook流
        ExtUtils.downLoadExcel("IT培优—指导老师量化表.xls", response,workbook );
    }
    /**
     * 上传文件批量创建用户
     * @param file excel文件
     */
    @PreAuthorize("hasRole('ADMIN')")
    @ApiOperation("上传学生模板")
    @PostMapping("/uploadUserModel")
    @WinControllerPointCut
    public void upload(@RequestParam MultipartFile file,HttpServletResponse response) throws Exception {
        //判断file是否为有效文件
        if(file==null||file.isEmpty()||!Objects.requireNonNull(file.getContentType()).startsWith(FILE_TYPE_OF_EXCEL)){
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write(new ObjectMapper().writeValueAsString(Result.failure("文件格式错误，只支持.xls/.xlsx文件")));
            return;
        }
        ImportParams params = new ImportParams();
        params.setHeadRows(2);
        params.setTitleRows(0);
        params.setNeedVerify(true);
        ExcelImportResult<UploadUser> uploadResult = null;
        uploadResult = ExcelImportUtil.importExcelMore(file.getInputStream(),
                UploadUser.class, params);
        if(!CollectionUtils.isEmpty(uploadResult.getList())) {
            int row = userService.batchCreateUser(uploadResult.getList());
        }
        ExtUtils.downLoadExcel("FailList.xls", response,uploadResult.getFailWorkbook());
    }
    @PreAuthorize("hasRole('ADMIN')")
    @ApiOperation("添加用户")
    @PostMapping("/addUser")
    @WinControllerPointCut
    public Result addUser(@RequestBody@Validated UploadUser user, BindingResult error){
        if (error.hasErrors()||user.getRoles()==null) {
            return Result.failure(ValidateHandler.catchErrors(error));
        }
        if (!"ROLE_PERSON".equals(user.getRoles())&&!"ROLE_USER".equals(user.getRoles())&&!"ROLE_ADMIN".equals(user.getRoles())) {
            return Result.failure("角色信息错误");
        }
        if (userService.addUser(user)) {
            log.info("添加的用户："+user.getRealName());
            return Result.success("添加成功");
        }return Result.failure("添加失败");
    }
    @PreAuthorize("hasAnyRole('ADMIN','USER')")
    @ApiOperation("下载小组培训记录")
    @PostMapping("/downloadGroupRecord")
    @WinControllerPointCut
    public void downloadGroupRecord(@RequestBody RecordParam param,HttpServletResponse response){
        //获取导出参数
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日HH时");
        String title = sdf.format(param.getStartDate())+"——"+sdf.format(param.getEndDate());
        ExportParams exportParams = new ExportParams(title, "sheet1", ExcelType.HSSF);
        //设置导出样式
        exportParams.setStyle(ExcelStyleUtil.class);
        //设置行高
        exportParams.setHeight((short) 15);
        List<GroupRecordExcel> records = recordService.getExcelRecordParam(param);
        //输出Workbook流
        Workbook workbook = ExtUtils.exportExcel(exportParams, GroupRecordExcel.class,records);
        String group = CollectionUtils.isEmpty(records)?"小组":records.get(0).getGroup()+"小组";
        ExtUtils.downLoadExcel("IT培优培训记录表—"+group+".xls", response,workbook );
    }
}
